home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 12 / Cream of the Crop 12 (Part II) / Cream of the Crop 12 (Part II).iso / OS2 / GNUSUTIL.ZIP / src / nice.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-17  |  7.2 KB  |  300 lines

  1. /* nice -- run a program with modified scheduling priority
  2.    Copyright (C) 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* David MacKenzie <djm@gnu.ai.mit.edu> */
  19.  
  20. #include <config.h>
  21.  
  22. #ifdef OS2
  23.  
  24. #define NICE
  25.  
  26. #define INCL_NOPM
  27. #define INCL_DOSPROCESS
  28. #include <os2.h>
  29. #include <errno.h>
  30.  
  31. #define PRIO_PROCESS 0
  32.  
  33. int class = PRTYC_NOCHANGE;
  34. int adjustment;
  35. char *current_class;
  36. char *name[] = {"", "idle-time", "regular", "time-critical", "foreground-server"};
  37.  
  38. int getpriority(int x, int y)
  39. {
  40.   ULONG prio, class;
  41.   PTIB ptib;
  42.   PPIB ppib;
  43.  
  44.   DosGetInfoBlocks(&ptib, &ppib);
  45.   prio = ptib -> tib_ptib2 -> tib2_ulpri;
  46.  
  47.   class = prio >> 8;
  48.   current_class = name[class];
  49.   return -(prio & 255);
  50. }
  51.  
  52. int setpriority(int x, int y, int v)
  53. {
  54.   return DosSetPriority(PRTYS_PROCESSTREE, class, -adjustment, 0) ? -1 : 0;
  55. }
  56.  
  57. #endif
  58.  
  59. #include <stdio.h>
  60.  
  61. #define NDEBUG
  62. #include <assert.h>
  63.  
  64. #include <getopt.h>
  65. #include <sys/types.h>
  66. #ifndef NICE_PRIORITY
  67. #include <sys/time.h>
  68. #include <sys/resource.h>
  69. #endif
  70.  
  71. #include "version.h"
  72. #include "system.h"
  73. #include "long-options.h"
  74.  
  75. #ifdef NICE_PRIORITY
  76. #define GET_PRIORITY() nice (0)
  77. #else
  78. #define GET_PRIORITY() getpriority (PRIO_PROCESS, 0)
  79. #endif
  80.  
  81. void error ();
  82.  
  83. static int isinteger ();
  84. static void usage ();
  85.  
  86. /* The name this program was run with. */
  87. char *program_name;
  88.  
  89. static struct option const longopts[] =
  90. {
  91.   {"adjustment", required_argument, NULL, 'n'},
  92. #ifdef OS2
  93.   {"idle-time", no_argument, NULL, 'i'},
  94.   {"regular", no_argument, NULL, 'r'},
  95.   {"time-critical", no_argument, NULL, 't'},
  96.   {"foreground-server", no_argument, NULL, 'f'},
  97. #endif
  98.   {NULL, 0, NULL, 0}
  99. };
  100.  
  101. void
  102. main (argc, argv)
  103.      int argc;
  104.      char **argv;
  105. {
  106.   int current_priority;
  107. #ifndef OS2
  108.   int adjustment = 0;
  109. #endif
  110.   int minusflag = 0;
  111.   int adjustment_given = 0;
  112.   int long_option_priority = 0;
  113.   int last_optind = 0;
  114.  
  115.   program_name = argv[0];
  116.   parse_long_options (argc, argv, "nice", version_string, usage);
  117.  
  118.   for (optind = 1; optind < argc; /* empty */)
  119.     {
  120.       char *s;
  121.  
  122.       s = argv[optind];
  123.  
  124.       if (s[0] == '-' && s[1] == '-' && ISDIGIT (s[2]))
  125.     {
  126.       if (!isinteger (&s[2]))
  127.         error (1, 0, "invalid option `%s'", s);
  128.  
  129.       minusflag = 1;
  130.       adjustment = atoi (&s[2]);
  131.       adjustment_given = 1;
  132.       long_option_priority = 1;
  133.       ++optind;
  134.     }
  135.       else
  136.     {
  137.       int optc;
  138. #ifdef OS2
  139.       while ((optc = getopt_long (argc, argv, "+0123456789n:irtf", longopts,
  140. #else
  141.       while ((optc = getopt_long (argc, argv, "+0123456789n:", longopts,
  142. #endif
  143.                       (int *) 0)) != EOF)
  144.         {
  145.           switch (optc)
  146.         {
  147.         case '?':
  148.           usage (1);
  149.  
  150. #ifdef OS2
  151.         case 'i':
  152.           class = PRTYC_IDLETIME;
  153.           break;
  154.         case 'r':
  155.           class = PRTYC_REGULAR;
  156.           break;
  157.         case 't':
  158.           class = PRTYC_TIMECRITICAL;
  159.           break;
  160.         case 'f':
  161.           class = PRTYC_FOREGROUNDSERVER;
  162.           break;
  163. #endif
  164.  
  165.         case 'n':
  166.           if (!isinteger (optarg))
  167.             error (1, 0, "invalid priority `%s'", optarg);
  168.           adjustment = atoi (optarg);
  169.           adjustment_given = 1;
  170.           break;
  171.  
  172.         default:
  173.           assert (ISDIGIT (optc));
  174.           /* Reset ADJUSTMENT if the last priority-specifying option
  175.              was not of the same type or if it was, but a separate
  176.              option.  */
  177.           if (long_option_priority ||
  178.               (adjustment_given && optind != last_optind))
  179.             {
  180.               long_option_priority = 0;
  181.               adjustment = 0;
  182.             }
  183.           adjustment = adjustment * 10 + optc - '0';
  184.           adjustment_given = 1;
  185.           last_optind = optind;
  186.         }
  187.         }
  188.       if (optc == EOF)
  189.         break;
  190.     }
  191.     }
  192.  
  193.   if (minusflag)
  194.     adjustment = -adjustment;
  195.   if (!adjustment_given)
  196.     adjustment = 10;
  197.  
  198.   if (optind == argc)
  199.     {
  200.       if (adjustment_given)
  201.     {
  202.       error (0, 0, "a command must be given with an adjustment");
  203.       usage (1);
  204.     }
  205.       /* No command given; print the priority. */
  206.       errno = 0;
  207.       current_priority = GET_PRIORITY ();
  208.       if (current_priority == -1 && errno != 0)
  209.     error (1, errno, "cannot get priority");
  210. #ifdef OS2
  211.       printf ("\ncurrent class: %s\ncurrent priority: %d\n",
  212.               current_class, current_priority);
  213.       usage (0);
  214. #else
  215.       printf ("%d\n", current_priority);
  216. #endif
  217.       exit (0);
  218.     }
  219.  
  220. #ifndef NICE_PRIORITY
  221.   errno = 0;
  222.   current_priority = GET_PRIORITY ();
  223.   if (current_priority == -1 && errno != 0)
  224.     error (1, errno, "cannot get priority");
  225.   if (setpriority (PRIO_PROCESS, 0, current_priority + adjustment))
  226. #else
  227.   if (nice (adjustment) == -1)
  228. #endif
  229.     error (1, errno, "cannot set priority");
  230.  
  231.   execvp (argv[optind], &argv[optind]);
  232.   error (errno == ENOENT ? 127 : 126, errno, "%s", argv[optind]);
  233. }
  234.  
  235. /* Return nonzero if S represents a (possibly signed) decimal integer,
  236.    zero if not. */
  237.  
  238. static int
  239. isinteger (s)
  240.      char *s;
  241. {
  242.   if (*s == '-' || *s == '+')
  243.     ++s;
  244.   if (*s == 0)
  245.     return 0;
  246.   while (*s)
  247.     {
  248.       if (!ISDIGIT (*s))
  249.     return 0;
  250.       ++s;
  251.     }
  252.   return 1;
  253. }
  254.  
  255. static void
  256. usage (status)
  257.      int status;
  258. {
  259.   if (status != 0)
  260.     fprintf (stderr, "Try `%s --help' for more information.\n",
  261.          program_name);
  262.   else
  263.     {
  264.       print_version("nice");
  265.       printf ("Usage: %s [OPTION]... [COMMAND [ARG]...]\n", program_name);
  266. #ifdef OS2
  267.       printf ("\
  268. \n\
  269.   -ADJUST                   increment priority by ADJUST\n\
  270.   -n, --adjustment=ADJUST   same as -ADJUST\n\
  271. \n\
  272.   -i, --idle-time        idle-time class\n\
  273.   -r, --regular            regular class\n\
  274.   -t, --time-critical        time-critical class\n\
  275.   -f, --foreground-server   foreground-server class\n\
  276. \n\
  277. Note that this program follows the Unix style which is that\n\
  278. negative adjustments increase the priority while positive\n\
  279. adjustments decrease the priority. Normally, all OS/2 processes\n\
  280. run at the lowest priority in their class already, so only\n\
  281. negative values make sense unless priority has been increased\n\
  282. previously, to allow a decrease later. Range of ADJUST goes from\n\
  283. -31 to 31. With no COMMAND, print the current scheduling priority.\n\
  284. ");
  285. #else
  286.       printf ("\
  287. \n\
  288.   -ADJUST                   increment priority by ADJUST first\n\
  289.   -n, --adjustment=ADJUST   same as -ADJUST\n\
  290.       --help                display this help and exit\n\
  291.       --version             output version information and exit\n\
  292. \n\
  293. With no COMMAND, print the current scheduling priority.  ADJUST is 10\n\
  294. by default.  Range goes from -20 (highest priority) to 19 (lowest).\n\
  295. ");
  296. #endif
  297.     }
  298.   exit (status);
  299. }
  300.